package proxy;

import net.IClient;
import register.MethodInfo;
import register.RegisterManager;
import sendRecieveWrapper.ICallerResponseTypeWrapper;
import sendRecieveWrapper.ICallerResponseTypeWrapperFactory;
import sendRecieveWrapper.SendRecieveManager;
import sync.ResponseManager;
import sync.RpcRequest;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class InvocationHandlerImp<T> implements InvocationHandler{
	
	private T t;
	
	private ResponseManager manager;
	
	private IClient channel;

	private RegisterManager registerManager;

	private SendRecieveManager sendRecieveManager;

	public InvocationHandlerImp(IClient channel,ResponseManager manager,RegisterManager registerManager,SendRecieveManager sendRecieveManager)
	{
		this.channel = channel;
		this.manager =manager;
		this.registerManager = registerManager;
		this.sendRecieveManager = sendRecieveManager;
	}
	

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		String methodName = method.getName();
		//处理烦人的父类方法
		switch (methodName) {
		case "equals":
			return proxy == args[0];
		case "hashCode":
			return hashCode();
		case "toString":
			return toString();
		default:
			break;
		}
		MethodInfo methodInfo = registerManager.getMethod(method);
		if(methodInfo==null){
			registerManager.register(method.getDeclaringClass());
			methodInfo = registerManager.getMethod(method);
		}

		//封装成 请求消息对象
		RpcRequest request = new RpcRequest();
		request.setName(methodInfo.getRequestName());
		//request.setRequestId(id);
		request.setArguments(args);
		if(!methodInfo.isNeedReturn())
		{
			//发送消息
			channel.sendRpcRequest(request);
			return null;
		}
		//处理函数返回
		ICallerResponseTypeWrapperFactory factory = sendRecieveManager.getICallerResponseTypeWrapperFactory(methodInfo.getReturnType());
		ICallerResponseTypeWrapper rpcHandler = factory.createRpcHandler();
		//创建回调
		manager.buildRequest(method,args,request,rpcHandler);
		//发送消息
		channel.sendRpcRequest(request);
		return rpcHandler.afterSend();
	}
}
